home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 140
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin
/
games
/
oyatsu
/
src
/
main.c
next >
Wrap
Text File
|
1999-11-22
|
7KB
|
280 lines
/*****************************************
推理パズル「おやつタイム」
メイン
*****************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys\iocs.h>
#include <sys\dos.h>
#include "oyatsu.h"
#include "screen.h"
#include "pad.h"
#include "sound.h"
#include "message.h"
/*** 条件 *******/
typedef struct {
int flag; /* 比較条件 */
int elm_kind; /* 比較種類 */
int num[3]; /* 番号 */
int pos; /* 表示位置 */
} CONDITION;
enum {EQUAL = 0, NOT_EQ}; /* 比較条件 */
static int right_ans[ELM_MAX][GIRL_MAX]; /* 解答 */
static CONDITION condition[GIRL_MAX]; /* 条件 */
/**********************************
数字を適当に並べる
戻り値 buf : 数字の並び
**********************************/
static
void shuffle(int buf[GIRL_MAX])
{
int i, j, t;
for (i = 0; i < GIRL_MAX; i++) { /* 順番に並べる */
buf[i] = i;
}
for (i = 0; i < GIRL_MAX; i++) { /* 並べ替え */
j = rnd(GIRL_MAX);
t = buf[i];
buf[i] = buf[j];
buf[j] = t;
}
}
/**************
条件表示
**************/
static
void print_condition(void)
{
CONDITION* p;
int girl[GIRL_MAX], junban[GIRL_MAX];
int i, k, n;
shuffle(girl); /* 発言順 */
shuffle(junban); /* 条件提示順 */
clear_screen(); /* 画面クリア */
for (i = 0; i < GIRL_MAX; i++) {
p = condition + junban[i]; /* 条件 */
if ( p->flag == EQUAL ) {
switch ( p->elm_kind ) {
case 0 : /* ~が買った */
n = (p->num[2] < 0) ? MES1A : MES2A;
break;
case 1 : /* ~が食べた */
n = (p->num[2] < 0) ? MES3A : MES4A;
break;
default : /* ~が買ったのを食べた */
n = MES5A;
break;
}
}
else { /* 買ってない、食べてない */
n = (p->elm_kind == 0) ? MES6A : MES7A;
}
k = (p->elm_kind == 2) ? 0 : 1;
if ( girl[i] == p->num[k] ) { /* 本人絡み */
n++;
}
else if ( girl[i] == p->num[k + 1] ) {
n += 2;
}
p->pos = print_message(girl[i], message_data[girl[i]] + n, p->num);
/* メッセージ表示 */
}
}
/**************
解答作成
**************/
static
void make_answer(void)
{
int i;
shuffle(right_ans[ELM_BUY]); /* 買った人 */
do {
shuffle(right_ans[ELM_EAT]); /* 食べた人 */
for (i = 0; i < GIRL_MAX; i++) {
if ( right_ans[ELM_BUY][i] == right_ans[ELM_EAT][i] ) {
break;
}
}
} while ( i < GIRL_MAX );
}
/**************
条件作成
**************/
static
void make_condition(void)
{
CONDITION* p;
int i, n[GIRL_MAX];
shuffle(n); /* 提示条件の番号 */
for (i = 0, p = condition; i < 3; i++, p++) {
p->flag = EQUAL;
p->elm_kind = i;
p->num[0] = (i < 2) ? n[i] : right_ans[ELM_BUY][n[i]];
p->num[1] = (i < 1) ? right_ans[ELM_BUY][n[i]] : right_ans[ELM_EAT][n[i]];
p->num[2] = -1;
}
i = rnd(2);
p->flag = NOT_EQ;
p->elm_kind = i;
p->num[0] = n[2];
p->num[1] = right_ans[(i == 0) ? ELM_BUY : ELM_EAT][n[3]];
p->num[2] = -1;
for (i = 0; i < GIRL_MAX; i++) {
if ( (i != right_ans[ELM_EAT][n[0]]) /* 正解 */
&& (i != right_ans[ELM_BUY][n[0]]) /* 前提条件 */
&& (i != right_ans[ELM_EAT][n[1]]) /* すでに出た条件 */
&& (i != right_ans[ELM_EAT][n[2]]) ) { /* すでに出た条件 */
condition[0].num[2] = i; /* 食べていない */
}
if ( (i != right_ans[ELM_BUY][n[1]]) /* 正解 */
&& (i != right_ans[ELM_EAT][n[1]]) /* 前提条件 */
&& (i != right_ans[ELM_BUY][n[0]]) /* すでに出た条件 */
&& (i != right_ans[ELM_BUY][n[2]]) ) { /* すでに出た条件 */
condition[1].num[2] = i; /* 買っていない */
}
}
}
/************************************
条件チェック
引数 p = 条件
ans = 回答
戻り値 条件に合っているか
************************************/
static
Bool check_condition(CONDITION* p, int ans[ELM_MAX][GIRL_MAX])
{
Bool f = TRUE;
int i;
switch ( p->elm_kind ) {
case 0 : /* 誰が買ったか */
f = (ans[ELM_BUY][p->num[0]] == p->num[1]);
if ( ans[ELM_EAT][p->num[0]] == p->num[2] ) {
f = FALSE;
}
break;
case 1 : /* 誰が食べたか */
f = (ans[ELM_EAT][p->num[0]] == p->num[1]);
if ( ans[ELM_BUY][p->num[0]] == p->num[2] ) {
f = FALSE;
}
break;
default : /* 買ったのを食べたのは */
for (i = 0; i < GIRL_MAX; i++) {
if ( ans[ELM_BUY][i] == p->num[0] ) {
f = (ans[ELM_EAT][i] == p->num[1]);
break;
}
}
break;
}
return (((p->flag == EQUAL) && f) || ((p->flag == NOT_EQ) && !f));
}
/************************************
ゲームメイン
戻り値 TRUE : ゲーム続行
FALSE : 終了
************************************/
static
Bool game_main(void)
{
static int answer[ELM_MAX][GIRL_MAX];
CONDITION* p;
int i, *p0, *p1;
set_food(); /* 菓子設定 */
make_answer(); /* 解答作成 */
make_condition(); /* 条件作成 */
print_condition(); /* 条件表示 */
if ( input_answer(answer) < 0 ) { /* 回答入力 */
return FALSE;
}
p0 = &right_ans[0][0]; /* 解答 */
p1 = &answer[0][0]; /* 回答 */
for (i = 0; i < GIRL_MAX*ELM_MAX; i++) {
if ( *p0++ != *p1++ ) {
break;
}
}
if ( i == GIRL_MAX*ELM_MAX ) { /* 正解 */
draw_atari();
}
else { /* 不正解 */
for (i = 0, p = condition; i < GIRL_MAX; i++, p++) {
if ( !check_condition(p, answer) ) { /* 条件に合わない */
draw_mujun1(p->pos); /* 枠描画 */
}
if ( answer[ELM_BUY][i] == answer[ELM_EAT][i] ) {
/* 前提に合わない */
draw_mujun2(i); /* 枠描画 */
}
}
draw_answer(1, right_ans); /* 解答表示 */
}
do { /* ボタン入力待ち */
v_synch();
if ( esc_key ) {
return FALSE;
}
} while ( !(get_push() & PAD_A) );
return TRUE;
}
/************
メイン
************/
int main(int argc, char* argv[])
{
_iocs_tgusemd(0, 2); /* グラフィック画面使用 */
_iocs_tgusemd(1, 2); /* テキスト画面使用 */
_dos_c_curoff(); /* カーソルOFF */
_iocs_crtmod(0x0c); /* 画面モード設定 */
_iocs_g_clr_on(); /* グラフィック画面表示 */
if ( init_screen() ) { /* 画面初期化 */
return 1;
}
if ( init_sound() ) { /* 音源初期化 */
return 1;
}
srand((unsigned int)_iocs_timeget()); /* 乱数初期化 */
play_music(MUSIC_MAIN); /* 演奏開始 */
while ( game_main() ); /* ゲームメイン */
stop_music(); /* 演奏停止 */
_iocs_tgusemd(0, 3); /* グラフィック画面使用 */
_iocs_tgusemd(1, 3); /* テキスト画面使用 */
_dos_c_width(0); /* 画面モード設定 */
_dos_c_curon(); /* カーソルON */
_dos_kflushio(0xff); /* キーバッファクリア */
return 0;
}
/************ End of File ******************************************************/